package service

import (
	"strconv"
	"strings"
	"time"
	"vrcm/src/vrcm/app/admin/models/live_schedule"
	dto "vrcm/src/vrcm/app/admin/service/dto/live_schedule"
	"vrcm/src/vrcm/common/service"
)

type ChannelStatisticsService struct {
	service.Service
}

// 记录任务启动记录用于统计
func (e *ChannelStatisticsService) CreateScheduleRecord(tenantId string, channelId int, taskId string, recordType int, now int64) error {
	schedule := live_schedule.ScheduleRecord{}
	schedule.TenantId = tenantId
	schedule.ChannelId = channelId
	schedule.ChannelTaskId = taskId
	schedule.StartTime = now
	schedule.EndTime = 0
	schedule.Type = recordType
	schedule.CreateTime = now
	schedule.UpdateTime = now
	err := e.Orm.Create(&schedule).Error
	if err != nil {
		e.Log.Errorf("save ScheduleRecord error:%s \r\n", err)
		return err
	}
	return nil
}

func (e *ChannelStatisticsService) GetScheduleStatistics(c *dto.GetScheduleStatisticsReq) ([]live_schedule.ScheduleRecord, error) {

	data := make([]live_schedule.ScheduleRecord, 0, 5)
	//获取结束时间不为空的数据
	data1 := make([]live_schedule.ScheduleRecord, 0, 5)
	db1 := e.Orm.Model(live_schedule.ScheduleRecord{}).Where("NOT ((end_time < ? OR (start_time > ?))) and end_time!=0 and type =?", c.StartTime, c.EndTime, c.Type)
	if len(c.TenantId) > 0 {
		db1.Where("tenant_id=?", c.TenantId)
	}
	if c.ChannelId > 0 {
		db1.Where("channel_id=?", c.ChannelId)
	}

	err := db1.Find(&data1).Error
	if err != nil {
		e.Log.Errorf("GetScheduleStatistics error:%s \r\n", err)
		return nil, err
	}

	//获取结束时间为空的数据
	data2 := make([]live_schedule.ScheduleRecord, 0, 5)
	db2 := e.Orm.Model(live_schedule.ScheduleRecord{}).Where("NOT (start_time > ?) and end_time=0 and type =?", c.EndTime, c.Type)
	if len(c.TenantId) > 0 {
		db2.Where("tenant_id=?", c.TenantId)
	}
	if c.ChannelId > 0 {
		db2.Where("channel_id=?", c.ChannelId)
	}

	err = db2.Find(&data2).Error
	if err != nil {
		e.Log.Errorf("GetScheduleStatistics error:%s \r\n", err)
		return nil, err
	}

	now := time.Now().Unix()
	for k, _ := range data2 {
		*(&data2[k].EndTime) = now
	}
	data = append(data, data1...)
	data = append(data, data2...)
	e.Log.Trace("获取统计数据", data)
	return data, nil
}

// 云直播流量
func (e *ChannelStatisticsService) GetScheduleFlowStatistics(c *dto.GetScheduleFlowReq) ([]dto.GetScheduleFlowRes, error) {

	res := make([]dto.GetScheduleFlowRes, 0, 4)
	streamNameMap := make(map[string]struct{})
	streamNamesMap := make(map[string][]string)
	channelIds := make([]int, 0, 5)
	db := e.Orm.Model(&live_schedule.ChannelBasic{}).Select("id")

	if c.ChannelId > 0 {
		db.Where("id=?", c.ChannelId)
	} else if len(c.TenantId) > 0 {
		db.Where("tenant_id=?", c.TenantId)
	}
	err := db.Find(&channelIds).Error
	if err != nil {
		e.Log.Errorf("get channelBasics error:%s \r\n", err)
		return res, err
	}

	//获取下车点
	offIds := make([]int, 0, 5)
	err = e.Orm.Model(&live_schedule.MediaOff{}).Select("off_id").Where("channel_id in ?", channelIds).Find(&offIds).Error
	if err != nil {
		e.Log.Errorf("get MediaOff error:%s \r\n", err)
		return res, err
	}

	offs := make([]live_schedule.TrafficOff, 0, 5)
	err = e.Orm.Model(&live_schedule.TrafficOff{}).Where("channel_id in ?", channelIds).Find(&offs).Error
	if err != nil {
		e.Log.Errorf("get TrafficOff error:%s \r\n", err)
		return res, err
	}
	offMap := make(map[int]live_schedule.TrafficOff)
	for _, v := range offMap {
		v := v
		offMap[v.Id] = v
	}
	histories := make([]live_schedule.ScheduleTaskHistory, 0, 5)
	db1 := e.Orm.Model(&live_schedule.ScheduleTaskHistory{})

	if c.ChannelId > 0 {
		db1.Where("channel_id=?", c.ChannelId)
	} else if len(c.TenantId) > 0 {
		db1.Where("tenant_id=?", c.TenantId)
	}
	err = db1.Find(&histories).Error
	if err != nil {
		e.Log.Errorf("get ScheduleTaskHistory error:%s \r\n", err)
		return res, err
	}

	for _, v := range histories {
		v := v
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}
		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.PullUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}
		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	channelTasks := make([]live_schedule.ChannelTask, 0, 5)
	err = e.Orm.Model(&live_schedule.ChannelTask{}).Where("channel_id in ?", channelIds).Find(&channelTasks).Error
	if err != nil {
		e.Log.Errorf("get ChannelTask error:%s \r\n", err)
		return res, err
	}
	for _, v := range channelTasks {
		v := v
		off := offMap[v.TrafficOffId]
		if len(v.TaskId) <= 0 || off.StreamType == 1 || len(v.OutUrl) <= 0 {
			continue
		}
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}
		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.OutUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}
		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	cortexTasks := make([]live_schedule.CortexTask, 0, 5)
	err = e.Orm.Model(&live_schedule.CortexTask{}).Where("channel_id in ?", channelIds).Find(&cortexTasks).Error
	if err != nil {
		e.Log.Errorf("get CortexTask error:%s \r\n", err)
		return res, err
	}
	for _, v := range cortexTasks {
		v := v
		off := offMap[v.TrafficOffId]
		if len(v.TaskId) <= 0 || off.StreamType == 1 || len(v.OutUrl) <= 0 {
			continue
		}
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}

		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.OutUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}

		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	channelTransCodeTasks := make([]live_schedule.ChannelTransCodeTask, 0, 5)
	err = e.Orm.Model(&live_schedule.ChannelTransCodeTask{}).Where("channel_id in ?", channelIds).Find(&channelTransCodeTasks).Error
	if err != nil {
		e.Log.Errorf("get ChannelTransCodeTask error:%s \r\n", err)
		return res, err
	}
	for _, v := range channelTransCodeTasks {
		v := v
		off := offMap[v.TrafficOffId]
		if len(v.TaskId) <= 0 || off.StreamType == 1 || len(v.OutUrl) <= 0 {
			continue
		}
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}
		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.OutUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}

		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	waterMarkTransTasks := make([]live_schedule.WaterMarkTransTask, 0, 5)
	err = e.Orm.Model(&live_schedule.WaterMarkTransTask{}).Where("channel_id in ?", channelIds).Find(&waterMarkTransTasks).Error
	if err != nil {
		e.Log.Errorf("get waterMarkTransTasks error:%s \r\n", err)
		return res, err
	}
	for _, v := range waterMarkTransTasks {
		v := v
		off := offMap[v.TrafficOffId]
		if len(v.TaskId) <= 0 || off.StreamType == 1 || len(v.OutUrl) <= 0 {
			continue
		}
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}
		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.OutUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}
		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	auditTasks := make([]live_schedule.AuditTask, 0, 5)
	err = e.Orm.Model(&live_schedule.AuditTask{}).Where("channel_id in ?", channelIds).Find(&auditTasks).Error
	if err != nil {
		e.Log.Errorf("get auditTasks error:%s \r\n", err)
		return res, err
	}
	for _, v := range auditTasks {
		v := v
		off := offMap[v.TrafficOffId]
		if len(v.TaskId) <= 0 || off.StreamType == 1 || len(v.OutUrl) <= 0 {
			continue
		}
		streamNames, ok := streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)]
		if !ok {
			streamNames = make([]string, 0, 5)
		}
		streamName := ""
		// 使用斜杠作为分隔符，将 URL 分割成多个部分
		parts := strings.Split(v.OutUrl, "/")

		// 获取最后一个斜杠后面的内容
		lastPart := parts[len(parts)-1]

		// 使用问号作为分隔符，将最后一个斜杠后面的内容分割成多个部分
		queryParts := strings.Split(lastPart, "?")
		// 获取第一个部分
		firstPart := queryParts[0]

		// 查找第一个点号的索引
		dotIndex := strings.Index(firstPart, ".")

		// 如果存在点号，则截取点号前面的内容
		if dotIndex != -1 {
			streamName = firstPart[:dotIndex]
		} else {
			streamName = firstPart
		}
		_, ok1 := streamNameMap[streamName]
		if ok1 {
			continue
		}
		streamNames = append(streamNames, streamName)
		streamNamesMap[v.TenantId+"^^"+strconv.Itoa(v.ChannelId)] = streamNames
	}

	for k, v := range streamNamesMap {
		v := v
		arr := strings.Split(k, "^^")
		tenantId := ""
		channelId := 0
		if len(arr) > 0 {
			tenantId = arr[0]
			id, _ := strconv.Atoi(arr[1])
			channelId = id
		}

		m := dto.GetScheduleFlowRes{}
		m.TenantId = tenantId
		m.ChannelId = channelId
		m.StreamNames = v
		res = append(res, m)
	}

	//e.Log.Trace("获取的流名为：", res)
	return res, nil
}
